﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace Cephei.Core
{
    public interface ITransaction : IDisposable
    {
        /// <summary>
        /// enlist this cell in the transaction.  Called by cells that are about to be calculated
        /// </summary>
        /// <param name="cell">the cell being added</param>
        void Join (ICell cell);
        /// <summary>
        /// remove this cell from the trasaction.  Called by cells that have been calculated
        /// </summary>
        /// <param name="cell">the cell that has been calculated</param>
        void Leave (ICell cell);
        /// <summary>
        /// enlist the cell in the transaction and use it.
        /// </summary>
        /// <param name="cell">the cell joining the transaction</param>
        /// <returns>the cell passed in</returns>
        ICell With (ICell cell);
        /// <summary>
        /// enlist a generic cell in the transaction and use it.
        /// </summary>
        /// <example>
        /// transaction.With&ltdouble&gt(aCell).Value = 23.2
        /// </example>
        /// <typeparam name="T">the type of the generic cell</typeparam>
        /// <param name="t">the cell being enlisted</param>
        /// <returns>the cell that was passed</returns>
        Generic.ICell<T> With<T> (Generic.ICell<T> t);
        IVector<T> With<T> (IVector<T> t);
        IMatrix<T> With<T> (IMatrix<T> t);
        ICube<T> With<T> (ICube<T> t);
        event TransactionComplete Complete;
        bool IsComplete { get; }

        /// <summary>
        /// Datetime marking the end of the Transaction Epoch
        /// </summary>
        DateTime Epoch { get; }

        /// <summary>
        /// Commit the transaction asyncronously and notify when done
        /// </summary>
        /// <param name="notify">the callback delegate to handle final completion</param>
        /// <param name="epoch">the timestamp to be applied to all the history items</param>
        void Commit (TransactionComplete notify, DateTime epoch);
        /// <summary>
        /// rollback the transaction asyncronously and notify when done
        /// </summary>
        /// <param name="notify">the callback delegate to handle final completion</param>
        void Rollback (TransactionComplete notify);

        void Lock ();
        void Unlock ();
    }
}
